iT邦幫忙

2025 iThome 鐵人賽

DAY 7
2

🎯 今日目標

昨天我們完成了邏輯面上的棋盤初始化與更新,今天開始進入 視覺化渲染階段。
我們會用 Ebiten 提供的 DrawRect 與 Image 功能,畫出一個簡單的 4x4 棋盤格背景,為後續數字渲染做準備。

🧠 學習重點

  1. Ebiten 畫布 (screen) 的概念
  • 每一幀 (Update) 完成邏輯更新後,Draw 會負責畫出畫面。
  • 畫面是用 ebiten.Image 物件組合而成。
  1. 棋盤格繪製邏輯
  • 設定格子大小,例如 tileSize := 100
  • 計算每格位置 (x, y) → tileX := col * tileSize,tileY := row * tileSize
  • 繪製格子時留適當間隔 (padding)
  1. 顏色與背景
  • 用 color.RGBA 設定背景顏色與格子顏色
  • 背景與格子分層畫,避免覆蓋錯位
  1. 固定畫面大小
  • ebiten.SetWindowSize(width, height)
  • 避免拉伸導致畫格比例跑掉

📜 範例程式碼

  1. layout 的部份
package layout

import (
	"image/color"

	"github.com/hajimehoshi/ebiten/v2"
)

const (
	tileSize  = 100
	gridSize  = 4
	padding   = 10
	WinWidth  = tileSize*gridSize + padding*(gridSize+1)
	WinHeight = tileSize*gridSize + padding*(gridSize+1)
)

type GameLayout struct{}

func (g *GameLayout) Draw(screen *ebiten.Image) {
	// 背景色
	screen.Fill(color.RGBA{250, 248, 239, 255})
	// 畫 4x4 格子
	for row := 0; row < gridSize; row++ {
		for col := 0; col < gridSize; col++ {
			op := &ebiten.DrawImageOptions{}
			x := padding + col*(tileSize+padding)
			y := padding + row*(tileSize+padding)
			rect := ebiten.NewImage(tileSize, tileSize)
			rect.Fill(color.RGBA{205, 193, 180, 255})
			op.GeoM.Translate(float64(x), float64(y))
			screen.DrawImage(rect, op)
		}
	}
}

func (g *GameLayout) Layout(outsideWidth, outsideHeight int) (int, int) {
	return WinWidth, WinHeight
}

func (g *GameLayout) Update() error {
	return nil
}

func NameGameLayout() *GameLayout {
	return &GameLayout{}
}
  1. main function
package main

import (
	"log"

	"github.com/hajimehoshi/ebiten/v2"
	"github.com/leetcode-golang-classroom/2048-game/internal/layout"
)
func main() {
	ebiten.SetWindowSize(layout.WinWidth, layout.WinHeight)
	ebiten.SetWindowTitle("2048 - Day 7 測試")
	game := layout.NameGameLayout()
	if err := ebiten.RunGame(game); err != nil {
		log.Fatal(err)
	}
}

Makefile

為了日後建制方便,所以開始建立 makefile 腳本

.PHONY=build

build-game:
	@CGO_ENABLED=1 GOOS=linux go build -o bin/2048-game cmd/main.go

run-game: build-game
	@./bin/2048-game

coverage:
	@go test -v -cover ./internal/game/...

test:
	@go test -v ./internal/game/...

由於 ebiten 畫面渲染需要使用到 cgo 所以在 build 的時候需要開啟 CGO_ENABLED 的 flag

實際執行

✅ 驗收條件

  • 執行程式後出現一個視窗
  • 背景色為淺色 (#FAF8EF)
  • 中間有 4x4 棋格,格子間有間隔
  • 每個格子為淺咖啡色 (#CDC1B4)

測試結果

https://github.com/leetcode-golang-classroom/2048-game/actions/runs/17104773005

📌 今日收穫

  • 學會使用 Ebiten 畫出靜態 2D 棋盤背景
  • 理解格子位置的計算方式(用 row/col 換算 pixel)
  • 對顏色與背景的分層繪製有初步認識

🔮 明日預告 (Day 8)

明天我們將 在格子中顯示數字與顏色變化,讓棋盤開始有「遊戲感」。
我們會根據不同數字設定不同顏色與文字大小,並學會用 text.Draw 在 Ebiten 上畫字。


上一篇
2048 遊戲: 實作其他方向滑動(上、右、下)
下一篇
2048 遊戲 - 顯示數字格與顏色
系列文
在 ai 時代 gopher 遊戲開發者的 30 天自我養成22
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言